/**
 * @file string_utils.h
 * @brief 通用字符串处理工具模块
 * @author 电网104协议开发团队
 * @date 2024
 */

#ifndef STRING_UTILS_H
#define STRING_UTILS_H

#include <stddef.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

/* ==================== 通用错误码定义 ==================== */

typedef enum {
    STRING_SUCCESS = 0,           /* 成功 */
    STRING_ERROR_NULL_POINTER,    /* 空指针错误 */
    STRING_ERROR_INVALID_PARAM,   /* 无效参数 */
    STRING_ERROR_BUFFER_OVERFLOW, /* 缓冲区溢出 */
    STRING_ERROR_INVALID_FORMAT   /* 无效格式 */
} string_error_t;

/* ==================== 字符串处理函数声明 ==================== */

/**
 * @brief 安全字符串复制
 * @details 安全地复制字符串，防止缓冲区溢出
 * 
 * @param dest 目标缓冲区
 * @param src 源字符串
 * @param dest_size 目标缓冲区大小
 * @return 字符串错误码
 */
string_error_t safe_strcpy(char* dest, const char* src, size_t dest_size);

/**
 * @brief 安全字符串连接
 * @details 安全地连接字符串，防止缓冲区溢出
 * 
 * @param dest 目标缓冲区
 * @param src 源字符串
 * @param dest_size 目标缓冲区大小
 * @return 字符串错误码
 */
string_error_t safe_strcat(char* dest, const char* src, size_t dest_size);

/**
 * @brief 安全字符串比较
 * @details 安全地比较字符串，防止缓冲区溢出
 * 
 * @param str1 字符串1
 * @param str2 字符串2
 * @param max_len 最大比较长度
 * @return 比较结果
 */
int safe_strcmp(const char* str1, const char* str2, size_t max_len);

/**
 * @brief 安全字符串长度计算
 * @details 安全地计算字符串长度，防止缓冲区溢出
 * 
 * @param str 字符串
 * @param max_len 最大长度限制
 * @return 字符串长度，如果超过限制返回max_len
 */
size_t safe_strlen(const char* str, size_t max_len);

/**
 * @brief 字符串转换为小写
 * @param str 字符串
 * @return 字符串错误码
 */
string_error_t str_to_lower(char* str);

/**
 * @brief 字符串转换为大写
 * @param str 字符串
 * @return 字符串错误码
 */
string_error_t str_to_upper(char* str);

/**
 * @brief 去除字符串首尾空白字符
 * @param str 字符串
 * @return 字符串错误码
 */
string_error_t str_trim(char* str);

/**
 * @brief 去除字符串左侧空白字符
 * @param str 字符串
 * @return 字符串错误码
 */
string_error_t str_ltrim(char* str);

/**
 * @brief 去除字符串右侧空白字符
 * @param str 字符串
 * @return 字符串错误码
 */
string_error_t str_rtrim(char* str);

/* ==================== 字符串转换函数 ==================== */

/**
 * @brief 字符串转整数
 * @param str 字符串
 * @param value 输出值
 * @param base 进制基数
 * @return 字符串错误码
 */
string_error_t str_to_int(const char* str, int* value, int base);

/**
 * @brief 字符串转长整数
 * @param str 字符串
 * @param value 输出值
 * @param base 进制基数
 * @return 字符串错误码
 */
string_error_t str_to_long(const char* str, long* value, int base);

/**
 * @brief 字符串转无符号整数
 * @param str 字符串
 * @param value 输出值
 * @param base 进制基数
 * @return 字符串错误码
 */
string_error_t str_to_uint(const char* str, unsigned int* value, int base);

/**
 * @brief 字符串转浮点数
 * @param str 字符串
 * @param value 输出值
 * @return 字符串错误码
 */
string_error_t str_to_float(const char* str, float* value);

/**
 * @brief 字符串转双精度浮点数
 * @param str 字符串
 * @param value 输出值
 * @return 字符串错误码
 */
string_error_t str_to_double(const char* str, double* value);

/**
 * @brief 整数转字符串
 * @param value 整数值
 * @param str 输出字符串
 * @param str_size 字符串缓冲区大小
 * @param base 进制基数
 * @return 字符串错误码
 */
string_error_t int_to_str(int value, char* str, size_t str_size, int base);

/**
 * @brief 无符号整数转字符串
 * @param value 无符号整数值
 * @param str 输出字符串
 * @param str_size 字符串缓冲区大小
 * @param base 进制基数
 * @return 字符串错误码
 */
string_error_t uint_to_str(unsigned int value, char* str, size_t str_size, int base);

/**
 * @brief 浮点数转字符串
 * @param value 浮点数值
 * @param str 输出字符串
 * @param str_size 字符串缓冲区大小
 * @param precision 精度
 * @return 字符串错误码
 */
string_error_t float_to_str(float value, char* str, size_t str_size, int precision);

/**
 * @brief 双精度浮点数转字符串
 * @param value 双精度浮点数值
 * @param str 输出字符串
 * @param str_size 字符串缓冲区大小
 * @param precision 精度
 * @return 字符串错误码
 */
string_error_t double_to_str(double value, char* str, size_t str_size, int precision);

/* ==================== 字符串格式化函数 ==================== */

/**
 * @brief 安全字符串格式化
 * @details 安全地格式化字符串，防止缓冲区溢出
 * 
 * @param str 目标字符串
 * @param str_size 字符串缓冲区大小
 * @param format 格式字符串
 * @param ... 参数列表
 * @return 字符串错误码
 */
string_error_t safe_sprintf(char* str, size_t str_size, const char* format, ...);

/**
 * @brief 安全字符串追加格式化
 * @details 安全地追加格式化字符串，防止缓冲区溢出
 * 
 * @param str 目标字符串
 * @param str_size 字符串缓冲区大小
 * @param format 格式字符串
 * @param ... 参数列表
 * @return 字符串错误码
 */
string_error_t safe_strcatf(char* str, size_t str_size, const char* format, ...);

/* ==================== 字符串搜索和替换函数 ==================== */

/**
 * @brief 查找子字符串
 * @param str 主字符串
 * @param substr 子字符串
 * @return 子字符串位置，未找到返回NULL
 */
char* str_find(const char* str, const char* substr);

/**
 * @brief 查找字符
 * @param str 字符串
 * @param ch 要查找的字符
 * @return 字符位置，未找到返回NULL
 */
char* str_find_char(const char* str, char ch);

/**
 * @brief 替换字符串中的子字符串
 * @param str 字符串
 * @param str_size 字符串缓冲区大小
 * @param old_substr 要替换的子字符串
 * @param new_substr 新的子字符串
 * @return 字符串错误码
 */
string_error_t str_replace(char* str, size_t str_size, const char* old_substr, const char* new_substr);

/* ==================== 字符串验证函数 ==================== */

/**
 * @brief 验证字符串是否为数字
 * @param str 字符串
 * @return 是数字返回1，否则返回0
 */
int str_is_numeric(const char* str);

/**
 * @brief 验证字符串是否为字母
 * @param str 字符串
 * @return 是字母返回1，否则返回0
 */
int str_is_alpha(const char* str);

/**
 * @brief 验证字符串是否为字母数字
 * @param str 字符串
 * @return 是字母数字返回1，否则返回0
 */
int str_is_alnum(const char* str);

/**
 * @brief 验证字符串是否为空或只包含空白字符
 * @param str 字符串
 * @return 为空或只包含空白字符返回1，否则返回0
 */
int str_is_empty(const char* str);

#ifdef __cplusplus
}
#endif

#endif /* STRING_UTILS_H */
